﻿using System;
using System.Collections.Generic;
using System.Text;
using QTPlugin;
using Kawanon.QtHoney;
using System.IO;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace Kawanon.Sessions
{
	[Serializable]
	public class Session
	{
		public string Title { get; set; }
		public byte[][] Folders { get; set; }

		public Session(string title, ITab[] tabs)
		{
			Title = title;
			Folders = Array.ConvertAll(tabs, delegate(ITab tab)
			{
				Address addr = tab.Address;
				return Utility.PidlFromAddress(addr);
			});
		}

		public override string ToString()
		{
			return Title;
		}
	}

	public class SessionManager
	{
		public SessionManagerInformation Information { get; set; }

		public SessionManager()
		{
			Information = Persistence.GetInformation<SessionManagerInformation>();
		}

		public void Open(IPluginServer server, Session s)
		{
			ITab[] tabs = server.GetTabs();

			Address[] addrs = Array.ConvertAll(s.Folders, delegate(byte[] bytes)
			{
				//NOTE: 特殊フォルダをPIDLで CreateTab に渡すとエラーとなるため、パスで渡す
				return new Address(Utility.PidlToPath(bytes));
			});

			List<string> paths = new List<string>();
			if (!Information.CloseOldTabs)
			{
				paths.AddRange(Array.ConvertAll(tabs, tab => Utility.AddressToPath(tab.Address)));
			}
			int index = (server.SelectedTab != null) ? server.SelectedTab.Index + 1 : 0;
			bool first = true;
			for (int i = 0; i < addrs.Length; i++)
			{
				string path = Utility.AddressToPath(addrs[i]);
				if (path == null)
				{
					// 文字列化できないパスは開けない
					continue;
				}
				if (Information.SkipAlreadyExists)
				{
					if (paths.Contains(path))
					{
						continue;
					}
				}

				server.CreateTab(addrs[i], i + index, false, first);
				first = false;
				paths.Add(path);
			}

			if (Information.CloseOldTabs)
			{
				Array.ForEach(tabs, tab => tab.Close());
			}
		}

		public bool Remove(Session s)
		{
			List<Session> list = new List<Session>(Load());
			int index = list.FindIndex(delegate(Session session)
			{
				return session.Title == s.Title;
			});
			if (index == -1)
			{
				return false;
			}
			list.RemoveAt(index);
			Save(list);
			return true;
		}

		public IEnumerable<Session> Load()
		{
			Stream stream = Persistence.CreateValueStream("Sessions");
			if (stream == null)
			{
				return new List<Session>();
			}
			return Persistence.UnpackArchive<Session>(stream);
		}

		public void Save(IEnumerable<Session> e)
		{
			Persistence.SaveBinary("Sessions", Persistence.CreateArchive(e));
		}
	}

	[Serializable]
	public class SessionManagerInformation
	{
		//public bool Enabled { get; set; }

		public bool SkipAlreadyExists { get; set; }

		public bool CloseOldTabs { get; set; }

		public SessionManagerInformation()
		{
			SkipAlreadyExists = true;
			CloseOldTabs = false;
		}
	}
}
